// 接口 interface 用来描述对象结构 

// 类型别名 type 用来给一个类型起个新名字
type PersonType = {
  name: string;
  age: number;
}

type NumberORString = number | string;

function handle(type: NumberORString) {
  console.log(type);
}
handle(123);
handle("123");
// handle(true) // 报错

// type PersonType = {
//   name: string;
//   age: number;
// } // 报错 重复定义

// 接口描述对象的结构
interface IPerson {
  name: string;
  age: number;
}

interface IPerson {
  sex: string;
}

const person: IPerson = {
  name: "张三",
  age: 18,
  sex: "男"
}

interface IStudent extends IPerson {
    grade: number;
}

const student: IStudent = {
  name: "张三",
  age: 18,
  grade: 1,
  sex: "男"
}

type StudentType = PersonType & { grade: number,sex:string};
const student2: StudentType = {
  name: "张三",
  age: 18,
  grade: 1,
  sex: "男"
}

// 接口描述函数对象的结构

interface IAdd {
  (num1: number, num2: number) : number;
  abc:()=>void;
  bcd:number
}
// 定义函数签名
type AddType = (num1: number, num2: number) => number;
// 实现函数的签名
const myAdd: AddType = (n1, n2) => {
  return n1 + n2;
}
const add: IAdd = (n1, n2) => {
  return n1 + n2;
}

add(1,2)
add.apply(window,[1,2])
add.call(window,1,2)
console.log(add.length)

add.abc=function(){
    console.log('abc')
}
add.bcd=123

console.log(add.bcd);



interface IClass{
    name:string;
    getName:()=>string;
}

class MyClass implements IClass{
    name:string;
    constructor(name:string){
        this.name=name
    }
    getName(){
        return this.name
    }
}




// 函数的构造签名
// function Animal(name,age){
//     this.name=name
//     this.age=age
// }

class Animal{
    name:string;
    age:number;
    constructor(name:string,age:number){
        this.name=name
        this.age=age
    }
}
interface IAnimal{
    new (name:string,age:number):Animal
}
// 获取Animal的实例
function getAnimalInstance(fn:IAnimal){
  return new fn("小猫",1)
}

getAnimalInstance(Animal)


// 总结：
// 1.类型别名和接口都可以用来描述对象的结构
// 2.类型别名可以描述任何类型
// 3.接口只能描述对象结构
// 4.接口可以重复定义，重复定义之后，接口会合并但是类型别名不行
// 5.接口可以继承,类型别名不行 (类型别名可以通过&来实现类似继承的效果)
// 6.接口可以描述函数类型，类型别名也可以描述函数类型
// ------>7.接口可以描述类类型，类型别名不行
// 8.接口可以被类实现，类型别名不行


export {}